#include<bits/stdc++.h>
#define int long long 
using namespace std;

const int maxn=2e5+10;

struct Edge{
	int left;
	int right;
	int val;
};

vector<Edge> edges;
vector<pair<int, int>> adj[maxn]; // 另一个端点以及 长度

// 对于一个点连接三条边的
// 需要对于 连接的边排序,再遍历取最大即可
// 对于 三条顺序的边
// 枚举边, 使用边的两个端点
// 每个端点取与他相连的最大值, 但是不能是中间这条边
// 所以需要给边进行编号
int n;

bool cmp(pair<int, int> p1, pair<int, int> p2){
	return p1.second > p2.second;
} 

// 左右端点
int get_max_val(int node, int otherNode){
	if(adj[node][0].first != otherNode){ // 不是同一条边
		return adj[node][0].second;
	}
	// 相等
	if(adj[node].size() < 2){ // 但是只有这一条边
		return 0;		
	}
	// 取第二条边
	return adj[node][1].second;
}

void solve(){
	cin>>n;
	for(int i=1;i<n;i++){
		Edge tmp;
		tmp.left=i+1;
		cin>>tmp.right;
		cin>>tmp.val;
		edges.push_back(tmp);
		adj[tmp.left].push_back({tmp.right, tmp.val});
		adj[tmp.right].push_back({tmp.left, tmp.val});
	}
	// 先考虑一个节点周围三条边的
	for(int i=1;i<=n;i++){
		sort(adj[i].begin(), adj[i].end(), cmp);
	}
	int mx=0;
	for(int i=1;i<=n;i++){
		if(adj[i].size()>=3){
			mx=max(mx, (adj[i][0].second+adj[i][1].second+adj[i][2].second));
		}
	}
	
	// 开始考虑三条顺序相连的边
	for(auto e: edges){
		int l=e.left;
		int r=e.right;
		int v=e.val;
		mx=max(mx, (v+get_max_val(l, r)+get_max_val(r, l)));
	}
	
	cout<<mx<<'\n';
	
}


signed main(){
	ios::sync_with_stdio(0), cin.tie(0),cout.tie(0);
	solve();
	return 0;
}
